﻿using DimOS.Constants;
using HAL = Cosmos.Hardware;

namespace DimOS.Plugs
{
    public class DateTime
    {
        public int Year { get; set; }

        public byte Month { get; set; }

        public byte Day { get; set; }

        public byte Hour { get; set; }

        public byte Minute { get; set; }

        public byte Second { get; set; }

        public DateTime(int year, byte month, byte day, byte hour, byte minute, byte second)
        {
            Year = year;
            Month = month;
            Day = day;
            Hour = hour;
            Minute = minute;
            Second = second;
        }

        public DateTime(int year, byte month, byte day)
        {
            Year = year;
            Month = month;
            Day = day;
            Hour = 0;
            Minute = 0;
            Second = 63; //60 and 61 are reserved for possibility of leap seconds
        }

        public DateTime(byte hour, byte minute)
        {
            Year = -1;
            Month = 0;
            Day = 0;
            Hour = hour;
            Minute = minute;
            Second = 62;
        }

        public static DateTime Now
        { get { return new DateTime(Convert.ToInt32(HAL.RTC.Century + "" + HAL.RTC.Year), HAL
         .RTC.Month, HAL.RTC.DayOfTheMonth, HAL.RTC.Hour, HAL.RTC.Minute, HAL.RTC.Second); } }

        public override string ToString()
        {
            var str = Day.ToString().PadLeft(2, '0') + Separators.DateDelimiter + Month.ToString
            ().PadLeft(2, '0') + Separators.DateDelimiter + Year.ToString().PadLeft(2, '0') +
            Tokens.Separator + Tokens.Space + Hour.ToString().PadLeft(2, '0') + Separators
            .TimeDelimiter + Minute.ToString().PadLeft(2, '0') + Separators.TimeDelimiter +
            Second.ToString().PadLeft(2, '0'); return str;
        }

        private static int CompareDate(DateTime required, DateTime target)
        {
            if (required.Year > target.Year || (required.Month > target.Month && required.Year == target.Year)
                || (required.Day > target.Day && required.Month == target.Month && required.Year == target.Year)) return 1;
            if (required.Year < target.Year || (required.Month < target.Month && required.Year == target.Year)
                || (required.Day < target.Day && required.Month == target.Month && required.Year == target.Year)) return -1;
            return 0;
        }

        private static int CompareTime(DateTime required, DateTime target)
        {
            if (required.Hour > target.Hour || (required.Minute > target.Minute && required.Hour == target.Hour)
                || ((required.Second < 62 && target.Second < 62) && required.Second > target.Second
                && required.Minute == target.Minute && required.Hour == target.Hour)) return 1;
            if (required.Hour < target.Hour || (required.Minute < target.Minute && required.Hour == target.Hour)
                || ((required.Second < 62 && target.Second < 62) && required.Second < target.Second
                && required.Minute == target.Minute && required.Hour == target.Hour)) return -1;
            return 0;
        }

        public static int Compare(DateTime required, DateTime target)
        {
            int result;
            if (required.Year == -1 || target.Year == -1) result = CompareTime(required, target);
            else if (required.Second == 63 || target.Second == 63) result = CompareDate(required, target);
            else
            {
                var temp = CompareDate(required, target);
                result = temp == 0 ? CompareTime(required, target) : temp;
            }
            return result;
        }
    }
}
